package com.hivekion.system.controller;

import com.hivekion.common.annotation.AutoLog;
import com.hivekion.common.entity.TreeNode;
import com.hivekion.common.enums.OperationTypeEnum;
import com.hivekion.common.exception.BusinessException;
import com.hivekion.common.utils;
import com.hivekion.system.domain.SysArea;
import com.hivekion.system.domain.vo.SysAreaCreateInputVo;
import com.hivekion.system.domain.vo.SysAreaUpdateInputVo;
import com.hivekion.system.domain.vo.SysAreaViewVo;
import com.hivekion.system.service.ISysAreaService;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.units.UnitsTools;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/system/area")
public class SysAreaController {
    @Autowired
    ISysAreaService areaService;

    @GetMapping("/getTreeSelect")
    public List<TreeNode> getTreeSelect() {
        return areaService.getTreeSelect();
    }

    @GetMapping("/getList")
    public List<SysAreaViewVo> getList() {
        return areaService.getList();
    }

    @GetMapping("/getChildrenList")
    public List<SysAreaViewVo> getChildrenList(String parentId) {
        List<SysArea> parentAreas = new ArrayList<>();
        if (parentId == null || parentId.equals("")) {
            parentAreas =
                    areaService.getAllList().stream()
                            .filter(x -> StringUtils.isBlank(x.getParentId()))
                            .sorted(Comparator.comparing(SysArea::getSortCode))
                            .collect(Collectors.toList());
        } else {
            parentAreas =
                    areaService.getAllList().stream()
                            .filter(x -> parentId.equals(x.getParentId()))
                            .sorted(Comparator.comparing(SysArea::getSortCode))
                            .collect(Collectors.toList());
        }
        List<SysAreaViewVo> sysAreaViewVos = new ArrayList<>();
        for (SysArea parentArea : parentAreas) {
            SysAreaViewVo sysAreaViewVo = new SysAreaViewVo();
            BeanUtils.copyProperties(parentArea, sysAreaViewVo);
            sysAreaViewVos.add(sysAreaViewVo);
        }
        return sysAreaViewVos;
    }

    @PostMapping("/add")
    @PreAuthorize("@Permission.hasPermi('area:add')")
    @AutoLog(value = "新增地区", operationType = OperationTypeEnum.INSERT, module = "系统管理/地区管理")
    public boolean add(@RequestBody SysAreaCreateInputVo inputVo) {
        if (inputVo.getName() == null
                || inputVo.getName().isEmpty()
                || inputVo.getName().equals("string")) {
            throw new BusinessException(501, "地区名称不能为空");
        }
        return areaService.create(inputVo);
    }

    @GetMapping("/getInfo")
    public SysArea getInfo(String areaId) {
        return areaService.getInfo(areaId);
    }


    @PostMapping("/checkNameUnique")
    public boolean checkNameUnique(String deptName, String deptId) {
        return areaService.checkAreaNameUnique(deptName, deptId);
    }

    @PutMapping("/edit")
    @PreAuthorize("@Permission.hasPermi('area:edit')")
    @AutoLog(value = "更改地区信息", operationType = OperationTypeEnum.UPDATE, module = "系统管理/地区管理")
    public boolean update(@RequestBody SysAreaUpdateInputVo inputVo) {
        if (inputVo.getId().equals(inputVo.getParentId())) {
            throw new BusinessException(500, "禁止选择本地区为父级地区");
        }
        //        if (areaService.checkAreaNameUnique(inputVo.getName(), "")) {
        //            throw new BusinessException(500, "地区名称重复");
        //        }
        return areaService.update(inputVo);
    }

    @DeleteMapping("/remove")
    @PreAuthorize("@Permission.hasPermi('area:remove')")
    @AutoLog(value = "删除地区", operationType = OperationTypeEnum.DELETE, module = "系统管理/地区管理")
    public boolean delete(String areaId) {
        return areaService.delete(areaId);
    }

    @GetMapping("/getPath")
    public String getPath(String pathId) {
        return areaService.getPath(pathId);
    }


    @PutMapping("/updateAreaTest")
    public boolean updateAreaTest() {
        List<String> ids = areaService.getAllList().stream().map(x -> x.getId()).collect(Collectors.toList());
        List<String> parentIds = areaService.getAllList().stream().map(x -> x.getParentId())
                .distinct()
                .collect(Collectors.toList());
        List<String> diffIds = utils.diffList(ids, parentIds);
        List<String> diffParentIds = areaService.getAllList().stream().filter(x -> diffIds.contains(x.getId()))
                .map(x -> x.getParentId())
                .distinct()
                .collect(Collectors.toList());

        for (String str : diffParentIds) {
            //
            List<SysArea> children = areaService.getAllList().stream().filter(x -> str.equals(x.getParentId()))
                    .collect(Collectors.toList());
            Optional<SysArea> first = areaService.getAllList().stream().filter(x -> str.equals(x.getId()))
                    .findFirst();
            if (first.isPresent()) {
                String code = first.get().getCode();
                for (SysArea area : children) {
                    int i = children.indexOf(area) + 1;
                    // 1000000 01
                    String format = new DecimalFormat("00").format(i);
                    area.setCode(code + format);
//                    areaService.updateById(area);
                }
//                areaService.saveOrUpdateBatch(children);
                areaService.updateBatchById(children);
            }
        }
//        this.areaService.saveBatch()
        return true;
    }

    private boolean updateTest(String parentId) {
        List<SysArea> children = areaService.getAllList().stream()
                .filter(x -> parentId.equals(x.getParentId()))
                .collect(Collectors.toList());
        for (SysArea area : children) {

        }
        return true;
    }
}
